#include<iostream>
#include<cstring>
#include<cassert>
using namespace std;
template<typename  iterator>
std::size_t  distance1(iterator begin,iterator end){
    std::size_t n=0;
    while(begin!=end){
        n++;
        begin++;
    }
    return n;
}
template<typename  T>
class Vector{
private:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef T* reverse_iterator;
    iterator start;
    iterator finish;
    iterator end_of_storage;
public:
    Vector()
            :start(nullptr),
             finish(nullptr),
             end_of_storage(nullptr){}

    Vector(int n,const T& t=T())
            :start(new T[n]),
             finish(start),
             end_of_storage(start+n){
        for(int i=0;i<n;i++)
            *finish++=t;
    }
    Vector(std::size_t n,const T& t=T())
            :start(new T[n]),
             finish(start),
             end_of_storage(start+n){
        for(int i=0;i<n;i++)
            *finish++=t;
    }
    template<typename  iterator>
    Vector(iterator begin,iterator end){
        std::size_t n=distance1(begin,end);
        this->start=new T[n];
        this->finish=this->start;
        this->end_of_storage=this->start+n;
        while(begin!=end){
            *(this->finish)=*begin;
            this->finish++;
            begin++;
        }
    }
    void swap(Vector<T> &v){
        std::swap(this->start,v.start);
        std::swap(this->finish,v.finish);
        std::swap(this->end_of_storage,v.end_of_storage);
    }
    Vector(const Vector<T>&v)
            : start(nullptr)
            , finish(nullptr)
            , end_of_storage(nullptr){
        Vector<T>temp(v.cbegin(),v.cend());
        this->swap(temp);
    }
    Vector<T>& operator=(Vector<T> v){
        this->swap(v);
        return *this;
    }
    ~Vector(){
        if(this->start){
            delete [] this->start;
            this->start= nullptr;
            this->finish= nullptr;
            this->end_of_storage= nullptr;
        }
    }
    void print(){
        iterator temp=start;
        int i=0;
        while(temp!=finish){
            cout<<i++<<':'<<*temp++<<endl;
        }
    }
    iterator begin(){
        return this->start;
    }
    iterator end(){
        return this->finish;
    }
    reverse_iterator rbegin(){
        return end();
    }
    reverse_iterator rend(){
        return begin();
    }
    const_iterator cbegin()const
    {
        return start;
    }

    const_iterator cend()const
    {
        return finish;
    }
    size_t  size()const{
        return this->finish-this->start;
    }
    std::size_t capacity()const{
        return this->end_of_storage-this->start;
    }
    bool empty()const{
        return this->start==this->finish;
    }
    void reserve(std::size_t newcapcaity){
        std::size_t n=this->size();
        if(newcapcaity>this->capacity()){
            iterator temp=new T[newcapcaity];
            if(this->start){
            for(int i=0;i<n;i++){
                temp[i]=this->start[i];
            }
            delete [] this->start;}
            this->start=temp;
            this->finish=this->start+n;
            this->end_of_storage=this->start+newcapcaity;
        }
    }
    void resize(std::size_t newsize,const T& value=T()){
        if(newsize>this->size()){
            if(newsize>this->capacity())
                this->reserve(newsize);
            for(int i=this->size();i<newsize;i++)
                this->start[i]=value;
        }
        this->finish=this->start+newsize;
    }
    T& operator[](std::size_t index)const{
        if(index<0||index>=this->size()){
            perror("index error");
            assert(false);
        }
        return this->start[index];
    }
    T& front()
    {
        // return start[0];
        return *begin();
    }

    const T& front()const
    {
        return start[0];
    }

    T& back()
    {
        return *(finish - 1);
    }

    const T& back()const
    {
        return *(finish - 1);
    }
    void push_back(const T& value=T()){
        if(this->finish==this->end_of_storage){
            this->reserve(this->capacity()*2);
        }
        *(this->finish)=value;
        this->finish++;
    }
    void pop_back(){
        if(this->empty()){
            perror("is empty");
            return;
        }
        this->finish--;
    }
    void insert(std::size_t index,const T& value=T()){
        if(index<0||index>this->size()){
            perror("index error");
            assert(false);
        }
        if(this->finish==this->end_of_storage){
            reserve(this->capacity()*2);
        }
        iterator temp=this->finish-1;
        while(temp>=this->start+index){
            *(temp+1)=*temp;
            temp--;
        }
        *(temp+1)=value;
        this->finish++;
    }
    void erase(std::size_t index){
        if(empty()){
            perror("is empty");
            return;
        }
        if(index<0||index>this->size()){
            perror("index error");
            assert(false);
        }
        iterator temp=this->start+index+1;
        while(temp!=this->finish){
            *(temp-1)=*temp;
            temp++;
        }
        this->finish--;
    }
    void clear()
    {
        finish = start;
    }
};